package com.ccx.demo.business.user.controller;

import com.ccx.demo.business.user.dto.TabRoleInsertDTO;
import com.ccx.demo.business.user.dto.TabRoleUpdateDTO;
import com.ccx.demo.business.user.entity.TabRole;
import com.ccx.demo.business.user.service.AuthorityService;
import com.ccx.demo.business.user.service.RoleService;
import com.ccx.demo.business.user.vo.Authority;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
import com.github.xiaoymin.knife4j.annotations.DynamicParameters;
import com.google.common.collect.Lists;
import com.support.annotations.VueSwaggerGroup;
import com.support.mvc.encrypt.AesApiId;
import com.support.mvc.entity.IUser;
import com.support.mvc.entity.base.Page;
import com.support.mvc.entity.base.Result;
import com.utils.enums.Code;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 对外接口：角色
 *
 * @author 谢长春 on 2019-08-29
 */
@Api(tags = "角色")
@ApiSort(3) // 控制接口排序
@RequestMapping("/role")
@Controller
@Slf4j
@RequiredArgsConstructor
public class RoleController {

    private final RoleService service;
    private final AuthorityService authorityService;

    @VueSwaggerGroup
    @ApiOperation(value = "1.获取全部权限配置树集合", tags = {""})
    @ApiOperationSupport(order = 1, author = "谢长春")
    @GetMapping("/authority/tree")
    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'role_list_load')")
    @ResponseBody
    public Result<Authority> tree(@ApiIgnore @AuthenticationPrincipal final IUser user) {
        return new Result<Authority>().execute(result -> result.setSuccess(Lists.newArrayList(authorityService.getTree())));
    }

    @VueSwaggerGroup
    @ApiOperation(value = "2.获取全部展开后的权限配置集合，可通过 parentCode 构造成权限树", tags = {""})
    @ApiOperationSupport(order = 2, author = "谢长春")
    @GetMapping("/authority/list")
    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'role_list_load')")
    @ResponseBody
    public Result<Authority> list(@ApiIgnore @AuthenticationPrincipal final IUser user) {
        return new Result<Authority>().execute(result -> result.setSuccess(authorityService.getList()));
    }

    //    @ApiOperation(value = "3.获取全部权限配置树集合", tags = {""})
//    @ApiOperationSupport(order = 3, author = "谢长春")
//    @GetMapping("/tree/hidden")
//    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_ADMIN_TEST', 'role_list_load')")
//    @ResponseBody
//    public Result<Authority> treeWww(@ApiIgnore @AuthenticationPrincipal final IUser user) {
//        return new Result<Authority>().execute(result -> result.setSuccess(Lists.newArrayList(service.getTreeCheckHidden(Sets.newHashSet()))));
//    }
//
//    @ApiOperation(value = "4.获取全部展开后的权限配置集合，可通过 parentCode 构造成权限树", tags = {""})
//    @ApiOperationSupport(order = 4, author = "谢长春")
//    @GetMapping("/list/hidden")
//    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_ADMIN_TEST', 'role_list_load')")
//    @ResponseBody
//    public Result<Authority> listWww(@ApiIgnore @AuthenticationPrincipal final IUser user) {
//        return new Result<Authority>().execute(result -> result.setSuccess(service.getListCheckHidden(Sets.newHashSet())));
//    }
    @VueSwaggerGroup
    @GetMapping("/page/{number}/{limit}")
    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'role_list_load')")
    @ApiOperation(value = "4.分页查询角色", tags = {""})
    @ApiOperationSupport(
            order = 4,
            author = "谢长春",
            includeParameters = {"number", "limit", "orderBy", "deleted", "name", "createUserId", "updateUserId"}
    )
    @ResponseBody
    public Result<TabRole> page(
            @ApiIgnore @AuthenticationPrincipal final IUser user,
            @ApiParam(required = true, value = "页码", example = "1") @PathVariable final int number,
            @ApiParam(required = true, value = "每页条数，最大值1000", example = "10") @PathVariable final int limit,
            final TabRole condition) {
        return new Result<TabRole>().execute(result -> result.setSuccess(service.page(
                condition,
                Page.builder().number(number).limit(limit).build()
        )));
    }

    @VueSwaggerGroup
    @GetMapping("/{encryptId}")
    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'role_list_load')")
    @ApiOperation(value = "5.按 encryptId 查询角色", tags = {""})
    @ApiOperationSupport(order = 5, author = "谢长春")
    @ResponseBody
    public Result<TabRole> findById(
            @ApiIgnore @AuthenticationPrincipal final IUser user,
            @ApiParam(required = true, value = "加密id", example = "encryptId") @PathVariable final String encryptId) {
        return new Result<TabRole>().execute(result -> {
            final AesApiId.AesId decrypt = AesApiId.decrypt(encryptId);
            result.setSuccess(service.findById(decrypt.getStringId()).orElse(null));
        });
    }

    @VueSwaggerGroup
    @PostMapping
    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'role_list_insert')")
    @ApiOperation(value = "6.新增角色", tags = {""})
//    @ApiImplicitParam(name = "body", dataType = "TabRoleInsertDTO", dataTypeClass = TabRoleInsertDTO.class, required = true)
    @ApiOperationSupport(
            order = 6,
            author = "谢长春",
            includeParameters = {
                    "body.name", "body.authorityTree"
            })
    @ResponseBody
    public Result<TabRole> insert(
            @ApiIgnore @AuthenticationPrincipal final IUser user,
            @RequestBody final TabRoleInsertDTO body) {
        return new Result<TabRole>().execute(result -> result.setSuccess(
                service.insert(body, user.getId())
        ));
    }

    @VueSwaggerGroup
    @PutMapping("/{encryptId}")
    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'role_list_update')")
    @ApiOperation(value = "7.修改角色", tags = {""})
    @ApiImplicitParam(name = "body", dataType = "TabRoleUpdateDTO", dataTypeClass = TabRoleUpdateDTO.class, required = true)
    @ApiOperationSupport(
            order = 7,
            author = "谢长春",
            includeParameters = {
                    "body.name", "body.authorityTree"
            })
    @ResponseBody
    public Result<Void> update(
            @ApiIgnore @AuthenticationPrincipal final IUser user,
            @ApiParam(required = true, value = "加密id", example = "encryptId") @PathVariable final String encryptId,
            @RequestBody final TabRoleUpdateDTO body) {
        return new Result<Void>().call(() -> {
            final AesApiId.AesId decrypt = AesApiId.decrypt(encryptId);
            body.setUpdateTime(decrypt.getUpdateTime());
            service.update(decrypt.getStringId(), user.getId(), body);
        });
    }

    @VueSwaggerGroup
    @PatchMapping("/{encryptId}")
    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'role_list_delete')")
    @ApiOperation(value = "8.逻辑删除角色", tags = {""})
    @ApiOperationSupport(order = 8, author = "谢长春")
    @ResponseBody
    public Result<Void> markDeleteById(
            @ApiIgnore @AuthenticationPrincipal final IUser user,
            @ApiParam(required = true, value = "加密id", example = "encryptId") @PathVariable final String encryptId) {
        return new Result<Void>().call(() -> {
            final AesApiId.AesId decrypt = AesApiId.decrypt(encryptId);
            service.markDeleteById(decrypt.getStringId(), decrypt.getUpdateTime(), user.getId());
        });
    }

    @VueSwaggerGroup
    @PatchMapping
    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'role_list_delete')")
    @ApiOperation(value = "9.批量逻辑删除角色表", tags = {""})
    @ApiOperationSupport(
            order = 9,
            author = "谢长春",
            params = @DynamicParameters(name = "EncryptIdArray", properties = {
                    @DynamicParameter(name = "EncryptIdArray", value = "加密id", example = "[encryptId,encryptId]", required = true, dataTypeClass = String[].class)
            })
    )
    @ResponseBody
    public Result<Void> markDelete(
            @ApiIgnore @AuthenticationPrincipal final IUser user,
            @RequestBody final Set<String> body
    ) {
        return new Result<Void>().call(() -> {
            Code.A00002.assertNonEmpty(body, "请至少选择一条数据");
            final List<AesApiId.AesId> decryptList = body.stream().map(AesApiId::decrypt).collect(Collectors.toList());
            service.markDelete(
                    decryptList.stream().map(AesApiId.AesId::getStringId).collect(Collectors.toSet())
                    , decryptList.stream().map(AesApiId.AesId::getUpdateTime).collect(Collectors.toSet())
                    , user.getId()
            );
        });
    }

    @VueSwaggerGroup
    @GetMapping("/options")
    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'role_list_load')")
    @ApiOperation(value = "10.获取所有有效角色列表", tags = {""})
    @ApiOperationSupport(order = 10, author = "谢长春")
    @ResponseBody
    public Result<TabRole> options(@ApiIgnore @AuthenticationPrincipal final IUser user) {
        return new Result<TabRole>().execute(result -> result.setSuccess(service.getOptions()));
    }

}
